package com.atmilan.quartz.utils.product;

import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.atmilan.quartz.config.RestTemplateConfig;
import com.atmilan.quartz.model.dto.buyer.BuyerProductResDTO;
import com.atmilan.quartz.utils.RestTemplateUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * 拉取商品源数据
 */

@Slf4j
@Service
public class BuyerProductUtil {

    @Autowired
    RestTemplateUtil restTemplateUtil;

    @Value("${buyer.url}")
    private String buyUrl;
    @Value("${buyer.appkey}")
    private String buyAppKey;
    @Value("${buyer.appsecret}")
    private String buyAppSecret;

    /**
     * 获取buyer商品数据和详情
     * @Description:
     * @author daigb
     * @param @param id 商品barCode
     * @param @return
     * @param @throws Exception
     * @return BuyerProductResDTO
     * @throws
     */
    public BuyerProductResDTO getBuyerProductByBarCode(String barCode) throws Exception {
        BuyerProductResDTO buyerProductResDTO = null;
        try {
            if (StringUtil.isEmpty(barCode) || 4 >= barCode.length()) {
                return null;
            }
            String id = barCode.substring(4, barCode.length());

            // log.info("--------------- 查询buyer远程数据, 商品id: {} ---------------", id);
            String timestamp = String.valueOf(Instant.now().getEpochSecond());
            String random = String.valueOf(ThreadLocalRandom.current().nextInt(1000, 9999));
            String signature = getSignature(timestamp, random);
            Map<String, String> parMap = new HashMap<String, String>();
            parMap.put("appkey", this.buyAppKey);
            parMap.put("appsecret", this.buyAppSecret);
            parMap.put("t", timestamp);
            parMap.put("r", random);
            parMap.put("s", signature);
            parMap.put("op", "goods");
            parMap.put("action", "list");
            parMap.put("goods_ids", id);
            String result = restTemplateUtil.getData(this.buyUrl + "?appkey={appkey}&appsecret={appsecret}&t={t}&r={r}&s={s}&op={op}&action={action}&goods_ids={goods_ids}", parMap);
            // log.info("--------------- buyer远程数据返回结果: {} ---------------", result);

            ObjectMapper mapper = new ObjectMapper();
            buyerProductResDTO = mapper.readValue(result, BuyerProductResDTO.class);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return buyerProductResDTO;
    }

    /**
     * 获取buyer商品列表
     * @Description:
     * @author daigb
     * @param @param pageNow
     * @param @param pageSize
     * @param @return
     * @param @throws Exception
     * @return BuyerProductResDTO
     * @throws
     */
    public BuyerProductResDTO selectBuyerPage(Integer pageNow, Integer pageSize) throws Exception {
        BuyerProductResDTO buyerProductResDTO = null;
        try {
            String timestamp = String.valueOf(Instant.now().getEpochSecond());
            String random = String.valueOf(ThreadLocalRandom.current().nextInt(1000, 9999));
            String signature = getSignature(timestamp, random);
            Map<String, String> parMap = new HashMap<String, String>();
            parMap.put("appkey", this.buyAppKey);
            parMap.put("appsecret", this.buyAppSecret);
            parMap.put("t", timestamp);
            parMap.put("r", random);
            parMap.put("s", signature);
            parMap.put("op", "goods");
            parMap.put("action", "list");
            parMap.put("p", pageNow + "");
            parMap.put("n", pageSize + "");
            parMap.put("stock", "1");
            String result = restTemplateUtil.getData(this.buyUrl + "?appkey={appkey}&appsecret={appsecret}&t={t}&r={r}&s={s}&op={op}&action={action}&p={p}&n={n}&stock={stock}", parMap);

            ObjectMapper mapper = new ObjectMapper();
            buyerProductResDTO = mapper.readValue(result, BuyerProductResDTO.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buyerProductResDTO;
    }

    // Buyer商品库存计算
    private Integer getBuyerStockByBarCode(String barCode, String color, String size) {
        int stock = 0;
        try {
            BuyerProductResDTO buyerProductResDTO = getBuyerProductByBarCode(barCode);
            if (null == buyerProductResDTO || StringUtil.isEmpty(color) || StringUtil.isEmpty(size)) {
                log.info("--------------- 查询buyer远程数据, 商品为空: {} 或参数缺失, color:{}, size: {} ---------------", null == buyerProductResDTO, color, size);
                return stock;
            }
            List<BuyerProductResDTO.Product> products = buyerProductResDTO.getProduct();
            if (CollectionUtils.isEmpty(products)) {
                log.info("--------------- 查询buyer远程数据, products为空, barCode:{}  ---------------", barCode);
                return stock;
            }
            List<BuyerProductResDTO.ProductSku> productSkus = products.get(0).getSkus();
            if (CollectionUtils.isEmpty(productSkus)) {
                log.info("--------------- 查询buyer远程数据, productSkus为空, barCode:{}  ---------------", barCode);
                return stock;
            }
            BuyerProductResDTO.ProductSku productSku = productSkus.stream().filter(obj -> obj.getColor().equals(color) && obj.getSize().equals(size)).findFirst().orElse(null);

            return null == productSku ? stock : productSku.getStock();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return stock;
    }

    // 签名
    private String getSignature(String timestamp, String random) {
        String signStr = null;
        try {
            Map<String, String> signMap = MapUtil.newHashMap(4);
            signMap.put("timeStamp", timestamp);
            signMap.put("randomStr", random);
            signMap.put("appkey", this.buyAppKey);
            signMap.put("appsecret", this.buyAppSecret);

            List<String> valueList = signMap.entrySet().stream().sorted(Map.Entry.comparingByValue()).map(Map.Entry::getValue).collect(Collectors.toList());
            signStr = String.join("", valueList);
            signStr = DigestUtil.sha1Hex(signStr);
            signStr = DigestUtil.md5Hex(signStr);
            signStr = DigestUtil.md5Hex(signStr);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return signStr.toUpperCase();
    }

}
